package ru.housewife.service.dishes;

import org.hibernate.Query;
import org.hibernate.Session;
import ru.housewife.form.CookingDishComponentForm;
import ru.housewife.form.IngredientForm;
import ru.housewife.form.WareForm;
import ru.housewife.model.CookingDishComponent;
import ru.housewife.model.CookingDishRecipe;
import ru.housewife.model.Ingredient;
import ru.housewife.model.Ware;
import ru.housewife.service.wares.AddNewWare;

import java.util.*;

/**
 * TODO: add description
 *
 * @author Alexander Troshanin
 */
public class DishHiberUtils {

    public static void addNewComponentsToRecipe(Session session, CookingDishRecipe recipe, Collection<CookingDishComponentForm> components) {

        Map<Long, Ware> waresMap = createWaresMap(session, components);
        Map<Long, Ingredient> ingredientsMap = createIngredientsMap(session, components);

        for (Iterator<CookingDishComponentForm> iter = components.iterator(); iter.hasNext();) {
            CookingDishComponentForm componentForm = iter.next();
            Ware ware = waresMap.get(componentForm.getPreferableWare().getId());
            Ingredient ingredient = ingredientsMap.get(componentForm.getIngredient().getId());
            if (ware != null && ingredient != null) {
                CookingDishComponent component = new CookingDishComponent();
                component.setCount(componentForm.getCount());
                component.setMeasure(componentForm.getMeasure());
                component.setRecipe(recipe);
                component.setPreferableWare(ware);
                component.setIngredient(ingredient);
                session.save(component);

                componentForm.setId(component.getId());
                recipe.getComponents().add(component);
            } else {
                iter.remove();
            }
        }
        
    }

    private static Map<Long, Ingredient> createIngredientsMap(Session session, Collection<CookingDishComponentForm> components) {
        if (components == null || components.isEmpty()) {
            return Collections.emptyMap();
        }
        List<Long> ingredientsIds = new LinkedList<Long>();
        for (CookingDishComponentForm componentForm : components) {
            IngredientForm ingredientForm = componentForm.getIngredient();
            ingredientsIds.add(ingredientForm.getId());
        }
        Query q = session.createQuery("select i from Ingredient i where i.id in (:ids)");
        q.setParameterList("ids", ingredientsIds);
        List<Ingredient> ingredients = q.list();
        Map<Long, Ingredient> result = new HashMap<Long, Ingredient>();
        for (Ingredient ingredient : ingredients) {
            result.put(ingredient.getId(), ingredient);
        }
        return result;
    }

    // TODO: fix problem with wares group - when adding new ware it MUST have group
    public static Map<Long, Ware> createWaresMap(Session session, Collection<CookingDishComponentForm> components) {
        if (components == null || components.isEmpty()) {
            return Collections.emptyMap();
        }
        List<Long> waresIds = new LinkedList<Long>();
        for (CookingDishComponentForm componentForm : components) {
            WareForm wareForm = componentForm.getPreferableWare();
            long wareId = wareForm.getId();
            if (wareId == 0) {
                if (!new AddNewWare(wareForm).execute(session)) {
                    continue;
                }
                // AddNewWare will set id to wareForm
                wareId = wareForm.getId();
            }
            waresIds.add(wareId);
        }
        Query q = session.createQuery("select w from Ware w where w.id in (:ids)");
        q.setParameterList("ids", waresIds);
        List<Ware> wares = q.list();
        Map<Long, Ware> result = new HashMap<Long, Ware>();
        for (Ware ware : wares) {
            result.put(ware.getId(), ware);
        }
        return result;
    }


}
